/*
 * gpio.c
 *
 *  Created on: Sep 13, 2013
 *      Author: Ken Arok
 */


#include "config_board.h"

#if BOARD_2_1_USED

#include <avr/io.h>
#include "board.h"
#include "gpio.h"


void gpio_configure_input(gpio_pin_t _gpio)
{
	uint8_t _idx;

	_idx = _gpio & 0x0F;

	switch(_gpio) {
		case PINA0_GPIO:
		case PINA1_GPIO:
		case PINA2_GPIO:
		case SPI_MEGA162_CS_GPIO:
		case PINA4_GPIO:
		case PINA5_GPIO:
		case PINA6_GPIO:
		case PINA7_GPIO:
			DDRA &= ~(1 << _idx);
		break;

		case SPI_SS_GPIO:
		case SPI_CLK_GPIO:
		case SPI_MOSI_GPIO:
		case SPI_MISO_GPIO:
		case PINB4_GPIO:
		case BUZZER_GPIO:
		case PINB6_GPIO:
		case PINB7_GPIO:
			DDRB &= ~(1 << _idx);
		break;

		case LCD_E_GPIO:
		case LCD_RW_GPIO:
		case LCD_RS_GPIO:
		case LCD_D4_GPIO:
		case LCD_D5_GPIO:
		case LCD_D6_GPIO:
		case LCD_D7_GPIO:
			DDRC &= ~(1 << _idx);
		break;

		case I2C_SCL_GPIO:
		case I2C_SDA_GPIO:
		case UART1_RX_GPIO:
		case UART1_TX_GPIO:
		case PIND4_GPIO:
		case PIND5_GPIO:
		case PIND6_GPIO:
		case PIND7_GPIO:
			DDRD &= ~(1 << _idx);
		break;

		case UART0_RX_GPIO:
		case UART0_TX_GPIO:
		case LED_HB_GPIO:
		case SPI_MMC_CS_GPIO:
		case PINE4_GPIO:
		case PINE5_GPIO:
		case PINE6_GPIO:
		case PINE7_GPIO:
			DDRE &= ~(1 << _idx);
		break;

		case KEY_COL1_GPIO:
		case KEY_COL2_GPIO:
		case KEY_COL3_GPIO:
		case KEY_COL4_GPIO:
		case KEY_ROW1_GPIO:
		case KEY_ROW2_GPIO:
		case KEY_ROW3_GPIO:
		case KEY_ROW4_GPIO:
			DDRF &= ~(1 << _idx);
		break;

		case PING0_GPIO:
		case LCD_BLON_GPIO:
		case PING2_GPIO:
		case PING3_GPIO:
		case PING4_GPIO:
			DDRG &= ~(1 << _idx);
		break;

		default: break;
	}
}


void gpio_configure_output(gpio_pin_t _gpio)
{
	uint8_t _idx;

	_idx = _gpio & 0x0F;

	switch(_gpio) {
		case PINA0_GPIO:
		case PINA1_GPIO:
		case PINA2_GPIO:
		case SPI_MEGA162_CS_GPIO:
		case PINA4_GPIO:
		case PINA5_GPIO:
		case PINA6_GPIO:
		case PINA7_GPIO:
			DDRA |= (1 << _idx);
		break;

		case SPI_SS_GPIO:
		case SPI_CLK_GPIO:
		case SPI_MOSI_GPIO:
		case SPI_MISO_GPIO:
		case PINB4_GPIO:
		case BUZZER_GPIO:
		case PINB6_GPIO:
		case PINB7_GPIO:
			DDRB |= (1 << _idx);
		break;

		case LCD_E_GPIO:
		case LCD_RW_GPIO:
		case LCD_RS_GPIO:
		case LCD_D4_GPIO:
		case LCD_D5_GPIO:
		case LCD_D6_GPIO:
		case LCD_D7_GPIO:
			DDRC |= (1 << _idx);
		break;

		case I2C_SCL_GPIO:
		case I2C_SDA_GPIO:
		case UART1_RX_GPIO:
		case UART1_TX_GPIO:
		case PIND4_GPIO:
		case PIND5_GPIO:
		case PIND6_GPIO:
		case PIND7_GPIO:
			DDRD |= (1 << _idx);
		break;

		case UART0_RX_GPIO:
		case UART0_TX_GPIO:
		case LED_HB_GPIO:
		case SPI_MMC_CS_GPIO:
		case PINE4_GPIO:
		case PINE5_GPIO:
		case PINE6_GPIO:
		case PINE7_GPIO:
			DDRE |= (1 << _idx);
		break;

		case KEY_COL1_GPIO:
		case KEY_COL2_GPIO:
		case KEY_COL3_GPIO:
		case KEY_COL4_GPIO:
		case KEY_ROW1_GPIO:
		case KEY_ROW2_GPIO:
		case KEY_ROW3_GPIO:
		case KEY_ROW4_GPIO:
			DDRF |= (1 << _idx);
		break;

		case PING0_GPIO:
		case LCD_BLON_GPIO:
		case PING2_GPIO:
		case PING3_GPIO:
		case PING4_GPIO:
			DDRG |= (1 << _idx);
		break;

		default: break;
	}
}


void gpio_enable_pullup(gpio_pin_t _gpio)
{
	uint8_t _idx;

	_idx = _gpio & 0x0F;

	switch(_gpio) {
		case PINA0_GPIO:
		case PINA1_GPIO:
		case PINA2_GPIO:
		case SPI_MEGA162_CS_GPIO:
		case PINA4_GPIO:
		case PINA5_GPIO:
		case PINA6_GPIO:
		case PINA7_GPIO:
			PORTA |= (1 << _idx);
		break;

		case SPI_SS_GPIO:
		case SPI_CLK_GPIO:
		case SPI_MOSI_GPIO:
		case SPI_MISO_GPIO:
		case PINB4_GPIO:
		case BUZZER_GPIO:
		case PINB6_GPIO:
		case PINB7_GPIO:
			PORTB |= (1 << _idx);
		break;

		case LCD_E_GPIO:
		case LCD_RW_GPIO:
		case LCD_RS_GPIO:
		case LCD_D4_GPIO:
		case LCD_D5_GPIO:
		case LCD_D6_GPIO:
		case LCD_D7_GPIO:
			PORTC |= (1 << _idx);
		break;

		case I2C_SCL_GPIO:
		case I2C_SDA_GPIO:
		case UART1_RX_GPIO:
		case UART1_TX_GPIO:
		case PIND4_GPIO:
		case PIND5_GPIO:
		case PIND6_GPIO:
		case PIND7_GPIO:
			PORTD |= (1 << _idx);
		break;

		case UART0_RX_GPIO:
		case UART0_TX_GPIO:
		case LED_HB_GPIO:
		case SPI_MMC_CS_GPIO:
		case PINE4_GPIO:
		case PINE5_GPIO:
		case PINE6_GPIO:
		case PINE7_GPIO:
			PORTE |= (1 << _idx);
		break;

		case KEY_COL1_GPIO:
		case KEY_COL2_GPIO:
		case KEY_COL3_GPIO:
		case KEY_COL4_GPIO:
		case KEY_ROW1_GPIO:
		case KEY_ROW2_GPIO:
		case KEY_ROW3_GPIO:
		case KEY_ROW4_GPIO:
			PORTF |= (1 << _idx);
		break;

		case PING0_GPIO:
		case LCD_BLON_GPIO:
		case PING2_GPIO:
		case PING3_GPIO:
		case PING4_GPIO:
			PORTG |= (1 << _idx);
		break;

		default: break;
	}
}


void gpio_disable_pullup(gpio_pin_t _gpio)
{
	uint8_t _idx;

	_idx = _gpio & 0x0F;

	switch(_gpio) {
		case PINA0_GPIO:
		case PINA1_GPIO:
		case PINA2_GPIO:
		case SPI_MEGA162_CS_GPIO:
		case PINA4_GPIO:
		case PINA5_GPIO:
		case PINA6_GPIO:
		case PINA7_GPIO:
			PORTA &= ~(1 << _idx);
		break;

		case SPI_SS_GPIO:
		case SPI_CLK_GPIO:
		case SPI_MOSI_GPIO:
		case SPI_MISO_GPIO:
		case PINB4_GPIO:
		case BUZZER_GPIO:
		case PINB6_GPIO:
		case PINB7_GPIO:
			PORTB &= ~(1 << _idx);
		break;

		case LCD_E_GPIO:
		case LCD_RW_GPIO:
		case LCD_RS_GPIO:
		case LCD_D4_GPIO:
		case LCD_D5_GPIO:
		case LCD_D6_GPIO:
		case LCD_D7_GPIO:
			PORTC &= ~(1 << _idx);
		break;

		case I2C_SCL_GPIO:
		case I2C_SDA_GPIO:
		case UART1_RX_GPIO:
		case UART1_TX_GPIO:
		case PIND4_GPIO:
		case PIND5_GPIO:
		case PIND6_GPIO:
		case PIND7_GPIO:
			PORTD &= ~(1 << _idx);
		break;

		case UART0_RX_GPIO:
		case UART0_TX_GPIO:
		case LED_HB_GPIO:
		case SPI_MMC_CS_GPIO:
		case PINE4_GPIO:
		case PINE5_GPIO:
		case PINE6_GPIO:
		case PINE7_GPIO:
			PORTE &= ~(1 << _idx);
		break;

		case KEY_COL1_GPIO:
		case KEY_COL2_GPIO:
		case KEY_COL3_GPIO:
		case KEY_COL4_GPIO:
		case KEY_ROW1_GPIO:
		case KEY_ROW2_GPIO:
		case KEY_ROW3_GPIO:
		case KEY_ROW4_GPIO:
			PORTF &= ~(1 << _idx);
		break;

		case PING0_GPIO:
		case LCD_BLON_GPIO:
		case PING2_GPIO:
		case PING3_GPIO:
		case PING4_GPIO:
			PORTG &= ~(1 << _idx);
		break;

		default: break;
	}
}


void gpio_set_pin_high(gpio_pin_t _gpio)
{
	uint8_t _idx;

	_idx = _gpio & 0x0F;

	switch(_gpio) {
		case PINA0_GPIO:
		case PINA1_GPIO:
		case PINA2_GPIO:
		case SPI_MEGA162_CS_GPIO:
		case PINA4_GPIO:
		case PINA5_GPIO:
		case PINA6_GPIO:
		case PINA7_GPIO:
			PORTA |= (1 << _idx);
		break;

		case SPI_SS_GPIO:
		case SPI_CLK_GPIO:
		case SPI_MOSI_GPIO:
		case SPI_MISO_GPIO:
		case PINB4_GPIO:
		case BUZZER_GPIO:
		case PINB6_GPIO:
		case PINB7_GPIO:
			PORTB |= (1 << _idx);
		break;

		case LCD_E_GPIO:
		case LCD_RW_GPIO:
		case LCD_RS_GPIO:
		case LCD_D4_GPIO:
		case LCD_D5_GPIO:
		case LCD_D6_GPIO:
		case LCD_D7_GPIO:
			PORTC |= (1 << _idx);
		break;

		case I2C_SCL_GPIO:
		case I2C_SDA_GPIO:
		case UART1_RX_GPIO:
		case UART1_TX_GPIO:
		case PIND4_GPIO:
		case PIND5_GPIO:
		case PIND6_GPIO:
		case PIND7_GPIO:
			PORTD |= (1 << _idx);
		break;

		case UART0_RX_GPIO:
		case UART0_TX_GPIO:
		case LED_HB_GPIO:
		case SPI_MMC_CS_GPIO:
		case PINE4_GPIO:
		case PINE5_GPIO:
		case PINE6_GPIO:
		case PINE7_GPIO:
			PORTE |= (1 << _idx);
		break;

		case KEY_COL1_GPIO:
		case KEY_COL2_GPIO:
		case KEY_COL3_GPIO:
		case KEY_COL4_GPIO:
		case KEY_ROW1_GPIO:
		case KEY_ROW2_GPIO:
		case KEY_ROW3_GPIO:
		case KEY_ROW4_GPIO:
			PORTF |= (1 << _idx);
		break;

		case PING0_GPIO:
		case LCD_BLON_GPIO:
		case PING2_GPIO:
		case PING3_GPIO:
		case PING4_GPIO:
			PORTG |= (1 << _idx);
		break;

		default: break;
	}
}


void gpio_set_pin_low(gpio_pin_t _gpio)
{
	uint8_t _idx;

	_idx = _gpio & 0x0F;

	switch(_gpio) {
		case PINA0_GPIO:
		case PINA1_GPIO:
		case PINA2_GPIO:
		case SPI_MEGA162_CS_GPIO:
		case PINA4_GPIO:
		case PINA5_GPIO:
		case PINA6_GPIO:
		case PINA7_GPIO:
			PORTA &= ~(1 << _idx);
		break;

		case SPI_SS_GPIO:
		case SPI_CLK_GPIO:
		case SPI_MOSI_GPIO:
		case SPI_MISO_GPIO:
		case PINB4_GPIO:
		case BUZZER_GPIO:
		case PINB6_GPIO:
		case PINB7_GPIO:
			PORTB &= ~(1 << _idx);
		break;

		case LCD_E_GPIO:
		case LCD_RW_GPIO:
		case LCD_RS_GPIO:
		case LCD_D4_GPIO:
		case LCD_D5_GPIO:
		case LCD_D6_GPIO:
		case LCD_D7_GPIO:
			PORTC &= ~(1 << _idx);
		break;

		case I2C_SCL_GPIO:
		case I2C_SDA_GPIO:
		case UART1_RX_GPIO:
		case UART1_TX_GPIO:
		case PIND4_GPIO:
		case PIND5_GPIO:
		case PIND6_GPIO:
		case PIND7_GPIO:
			PORTD &= ~(1 << _idx);
		break;

		case UART0_RX_GPIO:
		case UART0_TX_GPIO:
		case LED_HB_GPIO:
		case SPI_MMC_CS_GPIO:
		case PINE4_GPIO:
		case PINE5_GPIO:
		case PINE6_GPIO:
		case PINE7_GPIO:
			PORTE &= ~(1 << _idx);
		break;

		case KEY_COL1_GPIO:
		case KEY_COL2_GPIO:
		case KEY_COL3_GPIO:
		case KEY_COL4_GPIO:
		case KEY_ROW1_GPIO:
		case KEY_ROW2_GPIO:
		case KEY_ROW3_GPIO:
		case KEY_ROW4_GPIO:
			PORTF &= ~(1 << _idx);
		break;

		case PING0_GPIO:
		case LCD_BLON_GPIO:
		case PING2_GPIO:
		case PING3_GPIO:
		case PING4_GPIO:
			PORTG &= ~(1 << _idx);
		break;

		default: break;
	}
}


void gpio_write_port(gpio_port_t _port, uint8_t _data)
{
	switch(_port) {
		case PORTA_GPIO:
			PORTA = _data;
		break;

		case PORTB_GPIO:
			PORTB = _data;
		break;

		case PORTC_GPIO:
			PORTC = _data;
		break;

		case PORTD_GPIO:
			PORTD = _data;
		break;

		case PORTE_GPIO:
			PORTE = _data;
		break;

		case PORTF_GPIO:
			PORTF = _data;
		break;

		case PORTG_GPIO:
			PORTG = _data;
		break;

		default: break;
	}
}


void gpio_write_ddr(gpio_ddr_t _ddr, uint8_t _data)
{
	switch(_ddr) {
		case DDRA_GPIO:
			DDRA = _data;
		break;

		case DDRB_GPIO:
			DDRB = _data;
		break;

		case DDRC_GPIO:
			DDRC = _data;
		break;

		case DDRD_GPIO:
			DDRD = _data;
		break;

		case DDRE_GPIO:
			DDRE = _data;
		break;

		case DDRF_GPIO:
			DDRF = _data;
		break;

		case DDRG_GPIO:
			DDRG = _data;
		break;

		default: break;
	}
}


uint8_t gpio_read_port(gpio_port_t _port)
{
	uint8_t _data = 0x00;

	switch(_port) {
		case PORTA_GPIO:
			_data = PORTA;
		break;

		case PORTB_GPIO:
			_data = PORTB;
		break;

		case PORTC_GPIO:
			_data = PORTC;
		break;

		case PORTD_GPIO:
			_data = PORTD;
		break;

		case PORTE_GPIO:
			_data = PORTE;
		break;

		case PORTF_GPIO:
			_data = PORTF;
		break;

		case PORTG_GPIO:
			_data = PORTG;
		break;

		default: break;
	}

	return _data;
}


uint8_t gpio_read_ddr(gpio_ddr_t _ddr)
{
	uint8_t _data = 0x00;

	switch(_ddr) {
		case DDRA_GPIO:
			_data = DDRA;
		break;

		case DDRB_GPIO:
			_data = DDRB;
		break;

		case DDRC_GPIO:
			_data = DDRC;
		break;

		case DDRD_GPIO:
			_data = DDRD;
		break;

		case DDRE_GPIO:
			_data = DDRE;
		break;

		case DDRF_GPIO:
			_data = DDRF;
		break;

		case DDRG_GPIO:
			_data = DDRG;
		break;

		default: break;
	}

	return _data;
}


uint8_t gpio_read_pin(gpio_pins_t _pins)
{
	uint8_t _data = 0x00;

	switch(_pins) {
		case PINA_GPIO:
			_data = PINA;
		break;

		case PINB_GPIO:
			_data = PINB;
		break;

		case PINC_GPIO:
			_data = PINC;
		break;

		case PIND_GPIO:
			_data = PIND;
		break;

		case PINE_GPIO:
			_data = PINE;
		break;

		case PINF_GPIO:
			_data = PINF;
		break;

		case PING_GPIO:
			_data = PING;
		break;

		default: break;
	}

	return _data;
}


#endif /* BOARD_2_1_USED */
